-
-
Notifications
You must be signed in to change notification settings - Fork 213
Fix: Prevent intermittent zero energy reporting for tasks #853
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7a512a6
to
68b08ed
Compare
inimaz
approved these changes
Jun 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @benoit-cty !
Problem: EmissionsTracker.stop_task() would occasionally report zero energy consumed for a task, even when the task performed work and underlying hardware measurements indicated energy consumption. Cause: The issue stemmed from the `self._previous_emissions` instance variable, which is used to calculate energy deltas. This variable was being updated by a 'live API update' mechanism that could trigger during the manual call to `_measure_power_and_energy()` within `stop_task()`. If this live update occurred, `self._previous_emissions` would be set to the current total energy values *including* the task's consumption. Subsequently, when `stop_task()` attempted to calculate the task's specific delta, it would compare these updated totals against the (now also updated) `self._previous_emissions`, effectively calculating a delta between two identical states, resulting in zero. Solution: 1. Introduced a new instance variable `self._active_task_emissions_at_start` in `BaseEmissionsTracker`. 2. In `start_task()`, a snapshot (deep copy) of the `EmissionsData` (representing total accumulated energy up to that point) is taken using `self._prepare_emissions_data()` and stored in `self._active_task_emissions_at_start`. 3. In `stop_task()`: a. The energy delta for the completed task is now calculated by comparing the current total emissions (after the task's work) against the preserved `self._active_task_emissions_at_start` snapshot. This ensures the delta is specific to the task's duration and consumption. b. After the task-specific delta is determined, the global `self._previous_emissions` state is updated by calling `self._compute_emissions_delta()` with the current total emissions. This maintains the correct state for ongoing non-task-specific measurements or live API updates. c. `self._active_task_emissions_at_start` is cleared when the task stops. This change isolates the delta calculation for tasks from the global update mechanism for `_previous_emissions`, ensuring accurate energy reporting for individual tasks.
This commit adds a new unit test, `test_task_energy_with_live_update_interference`, to `tests/test_emissions_tracker.py`. The test is designed to: - Verify that `EmissionsTracker.stop_task()` correctly calculates task-specific energy consumption. - Specifically, it ensures accuracy even when an internal 'live API update' (triggered by `api_call_interval` being met during the `_measure_power_and_energy` call within `stop_task()`) occurs. This was the scenario that previously caused `_previous_emissions` to be updated prematurely, leading to intermittent zero-energy reporting for tasks. The test mocks hardware energy measurements (CPU and RAM) to return controlled, non-zero values and sets `api_call_interval=1` to reliably trigger the problematic condition. It then asserts that the `EmissionsData` returned by `stop_task()` reflects the correct, non-zero energy consumed during the task. This unit test complements the fix that ensures `_active_task_emissions_at_start` is used for task-specific delta calculations, safeguarding against regressions.
a914c77
to
c18ff0f
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem:
EmissionsTracker.stop_task() would occasionally report zero energy consumed for a task, even when the task performed work and underlying hardware measurements indicated energy consumption.
Cause:
The issue stemmed from the
self._previous_emissions
instance variable, which is used to calculate energy deltas. This variable was being updated by a 'live API update' mechanism that could trigger during the manual call to_measure_power_and_energy()
withinstop_task()
. If this live update occurred,self._previous_emissions
would be set to the current total energy values including the task's consumption. Subsequently, whenstop_task()
attempted to calculate the task's specific delta, it would compare these updated totals against the (now also updated)self._previous_emissions
, effectively calculating a delta between two identical states, resulting in zero.Solution:
self._active_task_emissions_at_start
inBaseEmissionsTracker
.start_task()
, a snapshot (deep copy) of theEmissionsData
(representing total accumulated energy up to that point) is taken usingself._prepare_emissions_data()
and stored inself._active_task_emissions_at_start
.stop_task()
: a. The energy delta for the completed task is now calculated by comparing the current total emissions (after the task's work) against the preservedself._active_task_emissions_at_start
snapshot. This ensures the delta is specific to the task's duration and consumption. b. After the task-specific delta is determined, the globalself._previous_emissions
state is updated by callingself._compute_emissions_delta()
with the current total emissions. This maintains the correct state for ongoing non-task-specific measurements or live API updates. c.self._active_task_emissions_at_start
is cleared when the task stops.This change isolates the delta calculation for tasks from the global update mechanism for
_previous_emissions
, ensuring accurate energy reporting for individual tasks.